﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Configuration;
using System.IO;
using System.Text;
using System.Data;

using HisGL.Crypto;
using HisGL.CA;
using HisGL.CA.NetCA;
using HisGL.Json;
using HisGL;
using HisGL.Log;

namespace NetCAService
{
  public class CAManager
  {
    private static CAManager instance = new CAManager();
    private string NetCAUrl = ConfigurationManager.AppSettings["NetCAUrl"].ToString();
    private string NetCACerFile = ConfigurationManager.AppSettings["NetCACerFile"].ToString();
    private string NetCACerPassword = ConfigurationManager.AppSettings["NetCACerPassword"].ToString();
    private string FtpSvrHost = ConfigurationManager.AppSettings["FtpSvrHost"].ToString();
    private string FtpSvrUser = ConfigurationManager.AppSettings["FtpSvrUser"].ToString();
    private string FtpSvrPassword = ConfigurationManager.AppSettings["FtpSvrPassword"].ToString();
    private string FtpRootPath = ConfigurationManager.AppSettings["FtpRootPath"].ToString();

    private static readonly string OAConnString = "OA";
    private static readonly string OAProviderName = "System.Data.SqlClient";

    private CAManager()
    {

    }

    public static CAManager Instance
    {
      get
      {
        return instance;
      }
    }

    public ResCA<string> DoAction(ReqApiCA req)
    {
      ResCA<string> res = new ResCA<string>();
      
      string data = CryptoHelper.DecodeBase64("utf-8", req.data);

      switch (req.func)
      {
        case "UserRegister": //注册用户          
          res = UserRegister(JsonHelper.JsonTo<ReqUserRegister>(data));
          break;
        case "UserUnLock": //8.3.用户解锁         
          res = UserUnLock(JsonHelper.JsonTo<ReqUserUnLock>(data));
          break;
        case "UserCertContentRevoke": //证书注销          
          res = UserCertContentRevoke(JsonHelper.JsonTo<ReqUserCertContent>(data));
          break;
        case "UserCertContentStatus": //9.22.证书状态查询          
          res = UserCertContentStatus(JsonHelper.JsonTo<ReqUserInfo>(data));
          break;

        case "UserCertContentParse": //2.6.解析证书属性及扩展 
          res = UserCertContentParse(JsonHelper.JsonTo<ReqUserCert>(data));
          break;

        case "CALogin": //  
          res = CALogin(JsonHelper.JsonTo<ReqCALogin>(data));
          break;

        case "CAQRLogin": //  
          res = CAQRLogin(JsonHelper.JsonTo<ReqCAQRLogin>(data));
          break;

        case "CAQRCode": //  
          res = CAQRCode(JsonHelper.JsonTo<ReqCAQRCode>(data));
          break;

        case "SealPdf": //2.4.3PDF同步签章  
          res = CASignPdf(JsonHelper.JsonTo<ReqCASignPdf>(data));
          break;

        case "PkiSignData": //9.7.电子P7签名  
          res = PkiSignData(JsonHelper.JsonTo<ReqCASign>(data));
          break;

        case "PkiVerifySignData": //验证签名  
          res = PkiVerifySignData(JsonHelper.JsonTo<ReqCAVerifySign>(data));
          break;

        case "CASignYWJL": //对业务记录签名  
          res = CASignYWJL(JsonHelper.JsonTo<ReqCAQM>(data));
          break;

        case "CASignYWJLZF": //作废签名记录  
          res = CASignYWJLZF(JsonHelper.JsonTo<ReqCAQMZF>(data));
          break;

        case "GetYWCAQMJLByJLID": //获取记录  
          res = GetYWCAQMJLByJLID(JsonHelper.JsonTo<ReqYWCAQMJLID>(data));
          break;

        case "GetYWCAQMJLByYWID": //获取记录  
          res = GetYWCAQMJLByYWID(JsonHelper.JsonTo<ReqYWCAQMJLYWID>(data));
          break;

        case "CASignYWPDF": //  对业务PDF签名
          res = CASignYWPDF(JsonHelper.JsonTo<ReqCAPDFQM>(data));
          break;
        case "CASignYWPDFZF": //作废业务PDF签名记录  
          res = CASignYWPDFZF(JsonHelper.JsonTo<ReqCAQMZF>(data));
          break;

        case "GetYWPDFCAQMJLByJLID": //获取PDF记录  
          res = GetYWPDFCAQMJLByJLID(JsonHelper.JsonTo<ReqYWCAQMJLID>(data));
          break;

        case "GetYWPDFCAQMJLByYWID": //获取PDF记录  
          res = GetYWPDFCAQMJLByYWID(JsonHelper.JsonTo<ReqYWCAQMJLYWID>(data));
          break;


      }
        

      return res;
    }

    private ResCA<string> UserRegister(ReqUserRegister req)
    {
      ResCA<string> res = new ResCA<string>();
      res.Code = -1;
      res.Data = "";
      using (NetCAApi CaApi = new NetCAApi(NetCAUrl, NetCACerFile, NetCACerPassword))
      {
        ResNetCA.CertContentInfoResponse resReg = CaApi.UserRegister1CKV11(req.AuthId, req.UserType, req.User);
        if (!resReg.ResponseResult.Success || !resReg.IsValid)
        {
          res.Message = resReg.ResponseResult.Message;
          return res;
        }

        res.Code = 0;
        res.Data = CryptoHelper.EncodeBase64("utf-8",JsonHelper.ToJson(resReg.Contents));

      }

      return res;
    }

    private ResCA<string> UserUnLock(ReqUserUnLock req)
    {
      ResCA<string> res = new ResCA<string>();
      res.Code = -1;
      res.Data = "";
      using (NetCAApi CaApi = new NetCAApi(NetCAUrl, NetCACerFile, NetCACerPassword))
      {
        ResNetCA.QueryCertResponse resSearch = CaApi.CertSearch(req.UserUid);
        if (!resSearch.ResponseResult.Success)
        {
          res.Message = resSearch.ResponseResult.Message;
          return res;

        }
        if (!resSearch.IsValid)
        {
          res.Message = string.Format("找不到{0}的相关证书", req.UserUid);
          return res;
        }

        ReqNetCA.Cert cert = new ReqNetCA.Cert();
        cert.CertContent = resSearch.Contents[req.UserUid].Count > 0 ? resSearch.Contents[req.UserUid][0] : string.Empty;

        ResNetCA.UserUnLockInfoResponse resReg = CaApi.UserUnLock2CKV6(req.AuthId, req.UserUid, req.Name, cert);
        if (!resReg.ResponseResult.Success || !resReg.IsValid)
        {
          res.Message = resReg.ResponseResult.Message;
          return res;
        }

        res.Code = 0;
        res.Data = CryptoHelper.EncodeBase64("utf-8", JsonHelper.ToJson(resReg.Contents));

      }

      return res;
    }

    private ResCA<string> UserCertContentRevoke(ReqUserCertContent req)
    {
      ResCA<string> res = new ResCA<string>();
      res.Code = -1;
      res.Data = "";
      using (NetCAApi CaApi = new NetCAApi(NetCAUrl, NetCACerFile, NetCACerPassword))
      {
        ResNetCA.QueryCertResponse resSearch = CaApi.CertSearch(req.UserUid);
        if(!resSearch.ResponseResult.Success)
        {
          res.Message = resSearch.ResponseResult.Message;
          return res;

        }
        if (!resSearch.IsValid)
        {
          res.Message = string.Format("找不到{0}的相关证书", req.UserUid);
          return res;
        }

        ReqNetCA.Cert cert = new ReqNetCA.Cert();
        cert.CertContent = resSearch.Contents[req.UserUid].Count > 0 ? resSearch.Contents[req.UserUid][0] : string.Empty;

        ResNetCA.CertContentRevokeResponse resRevoke = CaApi.UserCertContentRevoke2CKV11(req.AuthId, cert);
        if (!resRevoke.ResponseResult.Success || !resRevoke.IsValid)
        {
          res.Message = resRevoke.ResponseResult.Message;
          return res;
        }

        res.Code = 0;
      }

      return res;
    }

    /// <summary>
    /// 9.22.证书状态查询
    /// </summary>
    /// <param name="req"></param>
    /// <returns></returns>
    private ResCA<string> UserCertContentStatus(ReqUserInfo req)
    {
      ResCA<string> res = new ResCA<string>();
      res.Code = -1;
      res.Data = "";
      using (NetCAApi CaApi = new NetCAApi(NetCAUrl, NetCACerFile, NetCACerPassword))
      {
        ResNetCA.QueryCertResponse resSearch = CaApi.CertSearch(req.UserUid);
        if (!resSearch.ResponseResult.Success)
        {
          res.Message = resSearch.ResponseResult.Message;
          return res;

        }
        if (!resSearch.IsValid)
        {
          res.Message = string.Format("找不到{0}的相关证书", req.UserUid);
          return res;
        }

        ReqNetCA.Cert cert = new ReqNetCA.Cert();
        cert.CertContent = resSearch.Contents[req.UserUid].Count > 0 ? resSearch.Contents[req.UserUid][0] : string.Empty;

        ResNetCA.CertContentStatusInfoResponse resStatus = CaApi.UserCertContentStatus2CKV15(cert);
        if (!resStatus.ResponseResult.Success || !resStatus.IsValid)
        {
          res.Message = resStatus.ResponseResult.Message;
          return res;
        }

        res.Code = 0;
        res.Data = CryptoHelper.EncodeBase64("utf-8", JsonHelper.ToJson(resStatus.Contents));
      }

      return res;
    }

    private ResCA<string> UserCertContentParse(ReqUserCert req)
    {
      ResCA<string> res = new ResCA<string>();
      res.Code = -1;
      res.Data = "";
      using (NetCAApi CaApi = new NetCAApi(NetCAUrl))
      {

        ReqNetCA.Cert cert = new ReqNetCA.Cert();
        cert.CertContent = req.CertContent;

        ResNetCA.CertContentParseInfoResponse resParse = CaApi.UserCertContentParse1CKV13(cert);
        if (!resParse.ResponseResult.Success || !resParse.IsValid)
        {
          res.Message = resParse.ResponseResult.Message;
          return res;
        }

        res.Code = 0;
        res.Data = CryptoHelper.EncodeBase64("utf-8", JsonHelper.ToJson(resParse.Contents));
      }

      return res;
    }

      
    private ResCA<string> CALogin(ReqCALogin req)
    {
      ResCA<string> res = new ResCA<string>();
      res.Data = "";
      res.Code = -1;

      CALoginInfo resCALoginInfo = new CALoginInfo();

      if (req.UserUid == "")
      {
        res.Message = "传入用户工号为空！";
        return res;
      }

      ResCA<string> resCert = GetUserCert(req.UserUid);
      if (resCert.Code < 0)
      {
        res.Code = resCert.Code;
        res.Message = resCert.Message;
        return res;
      }

      string sUserCert = resCert.Data;
      //先查询证书
      using (NetCAApi CaApi = new NetCAApi(NetCAUrl))
      {
        //登录
        //使用当前输入的用户名登录
        ReqNetCA.Cert Cert = new ReqNetCA.Cert() { CertContent = sUserCert };
        ResNetCA.LoginResponse resLogin = CaApi.UserCertContentDoLogin(req.UserPin, Cert, req.ApplicationId);
        if (!resLogin.ResponseResult.Success)
        {
          res.Message = resLogin.ResponseResult.Message;
          //2.1.6证书用户口令重试次数
          ResNetCA.QueryPasswordRetryCountResponse resNum = CaApi.CertContentGetSurplusNum(Cert);
          if (!resNum.ResponseResult.Success)
          {
            res.Message = res.Message + "\r\n" + resNum.ResponseResult.Message;
          }
          else
          {
            res.Message = res.Message + "\r\n" + string.Format("还剩下{0}次后锁定！", resNum.Contents);
          }

          return res;
        }
        resCALoginInfo.UserToken = resLogin.Contents.UserToken;
        resCALoginInfo.UserUid = req.UserUid;

        res.Data = CryptoHelper.EncodeBase64("utf-8", JsonHelper.ToJson(resCALoginInfo));
        res.Code = 0;

      }

      return res;
    }

    private ResCA<string> CAQRLogin(ReqCAQRLogin req)
    {
      ResCA<string> res = new ResCA<string>();
      res.Data = "";
      res.Code = -1;

      CALoginInfo resCALoginInfo = new CALoginInfo();

      //先查询证书
      using (NetCAApi CaApi = new NetCAApi(NetCAUrl))
      {
        //登录
        //使用当前输入的用户名登录
        ResNetCA.QueryQrCodeStatusResponse resLogin = CaApi.QRCodeStatus(req.QRCodeIdentity);
        if (!resLogin.ResponseResult.Success)
        {
          res.Message = resLogin.ResponseResult.Message;
          return res;
        }

        if (resLogin.Contents.VerifyStatus == 0)
        {
          resCALoginInfo.UserToken = resLogin.Contents.UserToken;

          ResNetCA.OprInfoResponse resUid = CaApi.OprinfoSearch(resCALoginInfo.UserToken);
          if (!resUid.ResponseResult.Success)
          {
            res.Message = resUid.ResponseResult.Message;
            return res;
          }

          if (resUid.IsValid)
          {
            resCALoginInfo.UserUid = resUid.Contents.Uid;
          }

          res.Data = CryptoHelper.EncodeBase64("utf-8", JsonHelper.ToJson(resCALoginInfo));
          res.Code = 0;
        }
        else
        {
          res.Message = resLogin.Contents.ErrorMessage;

        }

      }

      return res;
    }

    private ResCA<string> CAQRCode(ReqCAQRCode req)
    {
      ResCA<string> res = new ResCA<string>();
      res.Data = "";
      res.Code = -1;

      CAQRCode resCAQRCode = new CAQRCode();

      using (NetCAApi CaApi = new NetCAApi(NetCAUrl))
      {
        if (req.UserUid != "")
        {
          ResCA<string> resCert = GetUserCert(req.UserUid);
          if (resCert.Code < 0)
          {
            res.Code = resCert.Code;
            res.Message = resCert.Message;
            return res;
          }
          ReqNetCA.Cert Cert = new ReqNetCA.Cert() { CertContent = resCert.Data };
          ResNetCA.GenerateQrCodeResponse resQR = CaApi.LoginQRCode(req.LoginTypeBitValue, Cert);
          if (!resQR.ResponseResult.Success)
          {
            res.Message = resQR.ResponseResult.Message;
            return res;
          }

          resCAQRCode.QRCodeBase64 = resQR.Contents.QrCodeBase64;
          resCAQRCode.QRCodeIdentity = resQR.Contents.QrCodeIdentity;
          resCAQRCode.QRExpireDate = resQR.Contents.QrCodeExpireDate;
          res.Data = CryptoHelper.EncodeBase64("utf-8", JsonHelper.ToJson(resCAQRCode));

          res.Code = 0;
        }
        else
        {
          ReqNetCA.Cert Cert = new ReqNetCA.Cert();
          ResNetCA.GenerateNoStatusQrCodeResponse resNS = CaApi.LoginQRCodeNoStatus2CKV1(req.LoginTypeBitValue, Cert);
          if (!resNS.ResponseResult.Success)
          {
            res.Message = resNS.ResponseResult.Message;
            return res;
          }

          if (resNS.Contents.QrCodes.Count == 0)
          {
            res.Message = "服务端响应返回的qrCodes字段为空";
            return res;
          }

          resCAQRCode.QRCodeBase64 = resNS.Contents.QrCodes[0].QrCodeBase64;
          resCAQRCode.QRCodeIdentity = resNS.Contents.QrCodeIdentity;
          resCAQRCode.QRExpireDate = resNS.Contents.QrCodeExpireDate;

          res.Data = CryptoHelper.EncodeBase64("utf-8", JsonHelper.ToJson(resCAQRCode));
          res.Code = 0;

        }

      }

      return res;
    }

    private ResCA<string> PkiSignData(ReqCASign req)
    {
      ResCA<string> res = new ResCA<string>();
      res.Data = "";
      res.Code = -1;
      req.OriginData = CryptoHelper.DecodeBase64("utf-8", req.OriginData);
      ResCA<CASign> resCASign = PkiSignData2(req);
      if (resCASign.Code < 0)
      {
          res.Message = resCASign.Message;
          return res;
      }
      res.Data = CryptoHelper.EncodeBase64("utf-8", JsonHelper.ToJson(resCASign.Data));
      res.Code = 0;

      return res;
    }

    private ResCA<CASign> PkiSignData2(ReqCASign req)
    {
        ResCA<CASign> res = new ResCA<CASign>();
        res.Code = -1;

        CASign resCASign = new CASign();

        using (NetCAApi CaApi = new NetCAApi(NetCAUrl))
        {
            ResNetCA.OprInfoResponse resUid = CaApi.OprinfoSearch(req.UserToken);
            if (!resUid.ResponseResult.Success)
            {
                res.Message = "CaApi.OprinfoSearch:" + resUid.ResponseResult.Message;
                return res;
            }
            if (resUid.IsValid)
            {
                resCASign.UserType = resUid.Contents.UserType;
                resCASign.UserUid = resUid.Contents.Uid;
                resCASign.AuthorizedUserId = resUid.Contents.AuthorizedUserId != null ? resUid.Contents.AuthorizedUserId : "";
            }

            string sOriginData = Convert.ToBase64String(Encoding.UTF8.GetBytes(req.OriginData));
            bool detached = false;  //False表示带原文
            bool useSubjectKeyId = false; //是否使用主体密钥标志符，默认为false

            ResNetCA.SignResponse resSign = CaApi.PkiSignData(sOriginData, detached, useSubjectKeyId, req.IncludeCertOption, req.UseQ7, req.UseTimestamp, req.UserToken);
            if (!resSign.ResponseResult.Success)
            {
                res.Message = resSign.ResponseResult.Message;
                return res;
            }
            resCASign.OriginDataBase64 = sOriginData;
            resCASign.SignedData = resSign.Contents.SignedData;
            resCASign.SignCert = resUid.Contents.CertContentInfo.SignCert;

            //下载签名图片
            if (req.DownLoadSealPic)
            {
                ResNetCA.DownloadSealResponse resSealPic = CaApi.SealDownloadSealPic(req.UserToken);
                if (!resSealPic.ResponseResult.Success)
                {
                    res.Message = "CaApi.SealDownloadSealPic:" + resSealPic.ResponseResult.Message;
                    return res;
                }

                resCASign.SealPicBase64 = resSealPic.Contents.SealImageBase64;
            }

            //验证签名
            if (req.NeedVerifySign)
            {
                bool includeCert = false;  //false 时不需要 ReqNetCA.Cert Cert ？
                ReqNetCA.Cert Cert = new ReqNetCA.Cert();
                if (req.IncludeCertOption != 0)
                {
                    includeCert = true;
                    Cert.CertContent = resCASign.SignCert; //签名证书 { CertContent = resUid.Contents.SignCert }
                }

                ResNetCA.BasicResponse resVerify = CaApi.PkiVerifySignData(sOriginData, detached, resCASign.SignedData, req.UseTimestamp, includeCert, Cert);
                if (!resVerify.ResponseResult.Success)
                {
                    res.Message = "CaApi.PkiVerifySignData:" + resVerify.ResponseResult.Message;
                    return res;
                }
            }

            res.Data = resCASign;
            res.Code = 0;
        }

        return res;
    }

    private ResCA<string> PkiVerifySignData(ReqCAVerifySign req)
    {
        ResCA<string> res = new ResCA<string>();
        res.Data = "";
        res.Code = -1;

        string sOriginData = Convert.ToBase64String(Encoding.UTF8.GetBytes(req.OriginData));
        bool detached = false;
        //bool useSubjectKeyId = false;
        //int includeCertOption = 0;
        //bool useQ7 = false;
        using (NetCAApi CaApi = new NetCAApi(NetCAUrl))
        {
          ReqNetCA.Cert Cert = new ReqNetCA.Cert();
          if (req.IncludeCert)
          {
            Cert.CertContent = req.CertContent; //签名证书 { CertContent = resUid.Contents.SignCert }
          }            
          ResNetCA.BasicResponse resVerify = CaApi.PkiVerifySignData(sOriginData, detached, req.SignedData, req.UseTimestamp, req.IncludeCert, Cert);
          if (!resVerify.ResponseResult.Success)
          {
              res.Message = "CaApi.PkiVerifySignData:" + resVerify.ResponseResult.Message;

              CAVerifySign VerifySign = new CAVerifySign();
              VerifySign.OriginDataBase64 = sOriginData;
              res.Data = CryptoHelper.EncodeBase64("utf-8", JsonHelper.ToJson(VerifySign)); 
              return res;
          }

          res.Code = 0;
        }

        return res;
    }

    private ResCA<string> CASignPdf(ReqCASignPdf req)
    {
      ResCA<string> res = new ResCA<string>();
      res.Data = "";
      res.Code = -1;

      ResCA<CASignPdf> resCASign = CASignPdf2(req);
      if (resCASign.Code < 0)
      {
          res.Message = resCASign.Message;
          return res;
      }
      res.Data = CryptoHelper.EncodeBase64("utf-8", JsonHelper.ToJson(resCASign.Data));
      res.Code = 0;

      return res;
    }

    private ResCA<CASignPdf> CASignPdf2(ReqCASignPdf req)
    {
        ResCA<CASignPdf> res = new ResCA<CASignPdf>();
        res.Code = -1;

        CASignPdf resCASignPdf = new CASignPdf();

        using (NetCAApi CaApi = new NetCAApi(NetCAUrl))
        {
            ResNetCA.OprInfoResponse resUid = CaApi.OprinfoSearch(req.UserToken);
            if (!resUid.ResponseResult.Success)
            {
                res.Message = "CaApi.OprinfoSearch:" + resUid.ResponseResult.Message;
                return res;
            }
            if (resUid.IsValid)
            {
                resCASignPdf.UserType = resUid.Contents.UserType;
                resCASignPdf.UserUid = resUid.Contents.Uid;
                resCASignPdf.AuthorizedUserId = resUid.Contents.AuthorizedUserId != null ? resUid.Contents.AuthorizedUserId : "";
            }

            //string sPdfData = Convert.ToBase64String(Encoding.UTF8.GetBytes(req.pdfData));
            string sPdfData = req.pdfData;
            if (sPdfData == "")
            {
                res.Message = "pdfData为空";
                return res;
            }

            ReqNetCA.SealSize sealSize = new ReqNetCA.SealSize { Width = req.Width, Height = req.Height };
            ReqNetCA.Position position = new ReqNetCA.Position { X = req.X, Y = req.Y, Page = req.Page };
            string fieldName = req.FieldName;
            string fieldText = req.FieldText;
            bool useFieldText = req.UseFieldText;

            ResNetCA.PDFSignSealResponse resSign = CaApi.SealPdf(sPdfData, sealSize, position, fieldName, fieldText, useFieldText, req.UseTimestamp, req.UserToken);
            if (!resSign.ResponseResult.Success)
            {
                res.Message = resSign.ResponseResult.Message;
                return res;
            }
            resCASignPdf.PDFBase64 = sPdfData;
            resCASignPdf.SignedPDFBase64 = resSign.Contents.SignedPDFBase64;
            resCASignPdf.SignCert = resUid.Contents.CertContentInfo.SignCert;

            //下载签名图片
            if (req.DownLoadSealPic)
            {
                ResNetCA.DownloadSealResponse resSealPic = CaApi.SealDownloadSealPic(req.UserToken);
                if (!resSealPic.ResponseResult.Success)
                {
                    res.Message = "CaApi.SealDownloadSealPic:" + resSealPic.ResponseResult.Message;
                    return res;
                }

                resCASignPdf.SealPicBase64 = resSealPic.Contents.SealImageBase64;
            }
            res.Data = resCASignPdf;
            res.Code = 0;
        }


        return res;
    }

    private ResCA<string> GetUserCert(string sUserUid)
    {
      ResCA<string> res = new ResCA<string>();
      res.Code = -1;

      //先查询证书
      using (NetCAApi CaApi = new NetCAApi(NetCAUrl))
      {
        ResNetCA.QueryCertResponse resCert = CaApi.CertSearch(sUserUid);

        if (!resCert.ResponseResult.Success)
        {
          res.Message = string.Format("查询证书失败：{0}", resCert.ResponseResult.Message);
          return res;
        }
        if (!resCert.IsValid)
        {
          res.Message = string.Format("找不到{0}的相关证书", sUserUid);
          return res;
        }

        //把查询到的证书缓存起来
        string id = sUserUid;
        // 由于大小写敏感，所以要先查找对应的真实用户ID
        foreach (string key in resCert.Contents.Keys)
        {
          if (key.Equals(id, StringComparison.CurrentCultureIgnoreCase))
          {
            id = key;
            break;
          }
        }
        var list = resCert.Contents[id];
        res.Data = list.Count > 0 ? list[0] : string.Empty;

        res.Code = 0;

      }
      return res;
    }

    private ResCA<string> CASignYWJL(ReqCAQM req)
    {
        ResCA<string> res = new ResCA<string>();
        res.Data = "";
        res.Code = -1;

        if (req.RYBM == "")
        {
            res.Message = "操作者(RYBM)为空！";
            return res;
        }

        if (req.YWID == "")
        {
            res.Message = "业务编号(YWID)为空！";
            return res;
        }

        if (req.YWLX < 0)
        {
            res.Message = "业务类型(YWLX)有误！";
            return res;
        }
        ResCA<string> resYWLX = CheckYWLX(req.YWLX);
        if (resYWLX.Code < 0)
        {
            res.Message = resYWLX.Message;
            return res;
        }

        ReqCASign reqSign = new ReqCASign();
        reqSign.OriginData = CryptoHelper.DecodeBase64("utf-8", req.OriginData);
        reqSign.UserToken = req.UserToken;
        reqSign.UseTimestamp = req.UseTimestamp;
        reqSign.UseQ7 = req.UseQ7;
        reqSign.IncludeCertOption = req.IncludeCertOption;
        reqSign.NeedVerifySign = true;
        reqSign.DownLoadSealPic = true;

        ResCA<CASign> resCASign = PkiSignData2(reqSign);
        if (resCASign.Code < 0)
        {
            res.Message = resCASign.Message;
            return res;
        }

        ResCA<CAQMJL> resQMJL = SaveQMJL(req, resCASign.Data);
        if (resQMJL.Code < 0)
        {
            res.Message = resQMJL.Message;
            return res;
        }
        if (!req.DownLoadSealPic)
        {
            resQMJL.Data.SealPicBase64 = "";
        }

        res.Data = CryptoHelper.EncodeBase64("utf-8", JsonHelper.ToJson(resQMJL.Data));
        res.Code = 0;

        return res;
    }

    private ResCA<string> CheckYWLX(int iYWLX)
    {
        ResCA<string> res = new ResCA<string>();
        res.Data = "";
        res.Code = -1;

        using (DbSession dbSession = new DbSession(OAProviderName, OAConnString))
        {
            dbSession.ClearSql();
            dbSession.AddSql(@"
SELECT * FROM CAGL_ZD_YWLX WHERE BM={0}
",
iYWLX
);
            LogHelper.WriteLog(dbSession.ToSqlString());
            DataTable dtLX = dbSession.Query();
            if (dtLX.Rows.Count == 0)
            {
                res.Message = string.Format("不存在业务类型为{0}记录", iYWLX);
                return res;
            }
            res.Data = ComonHelper.ToConvert<string>(dtLX.Rows[0], "MC", "");

            res.Code = 0;
        }
        return res;

    }

    private int GetQMJLID()
    {
        int res = 0;
        using (DbSession dbSession = new DbSession(OAProviderName, OAConnString))
        {
            dbSession.ClearSql();
            dbSession.AddSql(@"Exec PR_GetID {0}", 126);
            LogHelper.WriteLog(dbSession.ToSqlString());
            DataTable dt = dbSession.Query();
            if (!Convert.IsDBNull(dt.Rows[0]["ID"]))
            {
                res = Convert.ToInt32(dt.Rows[0]["ID"]);
            }
        }
        return res;
    }
    private string GetQMJLRQSJ(int iJLID,string sTable,string sRQField)
    {
        using (DbSession dbSession = new DbSession(OAProviderName, OAConnString))
        {
            dbSession.ClearSql();
            dbSession.AddSql(@"SELECT " + sRQField + " FROM [" + sTable + "] WHERE JLID={0}", iJLID);
            LogHelper.WriteLog(dbSession.ToSqlString());
            DataTable dt = dbSession.Query();
            DateTime dRQSJ = (DateTime)dt.Rows[0][sRQField];

            return dRQSJ.ToString("yyyy-MM-dd HH:mm:ss.fff");
        }
    }

    private DataTable GetQMJL(string sTable, int iJLID)
    {        
        using (DbSession dbSession = new DbSession(OAProviderName, OAConnString))
        {
            dbSession.ClearSql();
            dbSession.AddSql(@"SELECT * FROM [" + sTable + "] WHERE JLID={0}", iJLID);
            LogHelper.WriteLog(dbSession.ToSqlString());
            return dbSession.Query();

        }
    }

    private ResCA<CAQMJL> SaveQMJL(ReqCAQM req, CASign caSign)
    {
        ResCA<CAQMJL> res = new ResCA<CAQMJL>();
        res.Data = new CAQMJL();
        res.Code = -1;

        int iQMJL = GetQMJLID();
        if (iQMJL == 0)
        {
            res.Message = "获取签名记录ID有问题";
            return res;
        }
        string sYWSM =req.YWSM ;
        sYWSM = CryptoHelper.DecodeBase64("utf-8", sYWSM);
        try
        {
            using (DbSession dbSession = new DbSession(OAProviderName, OAConnString))
            {
                dbSession.ClearSql();
                dbSession.AddSql(@"
INSERT INTO CAGL_QMJL(JLID,YWID,YWDID,YWLX,RQSJ,RYBM,STATE,BZ,OriginData,SignedData,SealPicBase64,UseTimestamp,UserType,UserUid,AuthorizedUserId,UseQ7,IncludeCertOption,CertContent)
VALUES({0},{1},{2},{3},Getdate(),{4},{5},{6},{7},{8},{9},{10},{11},{12},{13},{14},{15},{16})
",
iQMJL, req.YWID, req.YWDID, req.YWLX, req.RYBM, 0, sYWSM, caSign.OriginDataBase64, caSign.SignedData,
caSign.SealPicBase64, (req.UseTimestamp?1:0), caSign.UserType, caSign.UserUid, caSign.AuthorizedUserId,
(req.UseQ7 ? 1 : 0), req.IncludeCertOption, caSign.SignCert
);
                LogHelper.WriteLog(dbSession.ToSqlString());
                dbSession.Execute();

                res.Data.JLID = iQMJL;
                res.Data.RQSJ = GetQMJLRQSJ(iQMJL, "CAGL_QMJL", "RQSJ");
                res.Data.SealPicBase64 = caSign.SealPicBase64;
                res.Code = 0;
            }
        }
        catch (Exception e)
        {
            res.Code = -99;
            res.Message = e.Message;
        }

        return res;

    }

    private ResCA<string> CASignYWJLZF(ReqCAQMZF req)
    {
        ResCA<string> res = new ResCA<string>();
        res.Data = "";
        res.Code = -1;

        if (req.JLID == 0)
        {
            res.Message = "记录编号(JLID)为空！";
            return res;
        }

        if (req.RYBM == "")
        {
            res.Message = "操作者(RYBM)为空！";
            return res;
        }

        DataTable dtQMJL = GetQMJL("CAGL_QMJL",req.JLID);
        if (dtQMJL.Rows.Count == 0)
        {
            res.Message = string.Format("没有找到编号为{0}的签名记录！", req.JLID);
            return res;
        }
        int iState = ComonHelper.ToConvert<int>(dtQMJL.Rows[0], "STATE", 0);
        int iUserType = ComonHelper.ToConvert<int>(dtQMJL.Rows[0], "UserType", 0);
        string sUserUid = ComonHelper.ToConvert<string>(dtQMJL.Rows[0], "UserUid", "");
        string sAuthorizedUserId = ComonHelper.ToConvert<string>(dtQMJL.Rows[0], "AuthorizedUserId", "");
        if (iState == 1)
        {
            res.Message = string.Format("编号为{0}的签名记录已经作废，不必再作废！", req.JLID);
            return res;
        }

        if (req.NeedCheckUserUid)
        {
            if (req.UserToken == "")
            {
                res.Message = "用户(Token)为空！";
                return res;
            }
            using (NetCAApi CaApi = new NetCAApi(NetCAUrl))
            {
                ResNetCA.OprInfoResponse resUid = CaApi.OprinfoSearch(req.UserToken);
                if (!resUid.ResponseResult.Success)
                {
                    res.Message = "CaApi.OprinfoSearch:" + resUid.ResponseResult.Message;
                    return res;
                }
                if (resUid.IsValid)
                {
                    if (iUserType == 0) //本人签名的
                    {
                        if (sUserUid != resUid.Contents.Uid && sUserUid != resUid.Contents.AuthorizedUserId)
                        {
                            res.Message = string.Format("你没有权限作废用户{0}的签名记录！", sUserUid);
                            return res;
                        }
                    }
                    else
                    {
                        if (sAuthorizedUserId != resUid.Contents.Uid && sAuthorizedUserId != resUid.Contents.AuthorizedUserId)
                        {
                            res.Message = string.Format("你没有权限作废用户{0}的签名记录！", sAuthorizedUserId);
                            return res;
                        }
                    }
                }
                else
                {
                    res.Message = string.Format("用户Token有问题！", req.UserToken);
                    return res;
                }
            }

        }

        ResCA<CAQMZFJL> resZFQMJL = CancelQMJL(req);
        if (resZFQMJL.Code < 0)
        {
            res.Message = resZFQMJL.Message;
            return res;
        }

        res.Data = CryptoHelper.EncodeBase64("utf-8", JsonHelper.ToJson(resZFQMJL.Data));
        res.Code = 0;

        return res;
    }

    private ResCA<CAQMZFJL> CancelQMJL(ReqCAQMZF req)
    {
        ResCA<CAQMZFJL> res = new ResCA<CAQMZFJL>();
        res.Data = new CAQMZFJL();
        res.Code = -1;


        string sZFSM = req.ZFSM;
        sZFSM = CryptoHelper.DecodeBase64("utf-8", sZFSM);
        try
        {
            using (DbSession dbSession = new DbSession(OAProviderName, OAConnString))
            {
                dbSession.ClearSql();
                dbSession.AddSql(@"
UPDATE CAGL_QMJL SET STATE = 1,ZFRYBM={1},ZFBZ={2},ZFRQSJ=Getdate()
WHERE JLID={0}
",
req.JLID, req.RYBM, sZFSM
);
                LogHelper.WriteLog(dbSession.ToSqlString());
                dbSession.Execute();

                res.Data.RQSJ = GetQMJLRQSJ(req.JLID, "CAGL_QMJL", "ZFRQSJ");
                res.Code = 0;
            }
        }
        catch (Exception e)
        {
            res.Code = -99;
            res.Message = e.Message;
        }

        return res;

    }

    private ResCA<string> GetYWCAQMJLByJLID(ReqYWCAQMJLID req)
    {
        ResCA<string> res = new ResCA<string>();
        res.Data = "";
        res.Code = -1;
        if (req.JLID < 0)
        {
            res.Message = "记录ID(JLID)有误！";
            return res;
        }

        int iLimit = 1000;
        int iPage = 1;
        int iSumCount = 0;
        string sOrderBy = "JL.JLID";
        Dictionary<string, object> dicWheres = new Dictionary<string, object>();
        dicWheres.Add("AND JL.JLID={0} ", req.JLID);

        ResCA<DataTable> resJL = GetYWCAQMJL(dicWheres, sOrderBy, iPage, iLimit, ref iSumCount);
        if (resJL.Code < 0)
        {
            res.Message = resJL.Message;
            return res;
        }

        res.Data = CryptoHelper.EncodeBase64("utf-8", JsonHelper.ToJson(resJL.Data));
        res.Code = 0;

        return res;
    }

    private ResCA<string> GetYWCAQMJLByYWID(ReqYWCAQMJLYWID req)
    {
        ResCA<string> res = new ResCA<string>();
        res.Data = "";
        res.Code = -1;
        if (req.YWID == "")
        {
            res.Message = "业务编号(YWID)为空！";
            return res;
        }

        if (req.YWLX < 0)
        {
            res.Message = "业务类型(YWLX)有误！";
            return res;
        }


        int iLimit = 1000;
        int iPage = 1;
        int iSumCount = 0;
        string sOrderBy = "JL.JLID";

        Dictionary<string, object> dicWheres = new Dictionary<string, object>();
        dicWheres.Add("AND JL.YWLX = {0}", req.YWLX);
        dicWheres.Add("AND JL.YWID = {0}", req.YWID);
        if (req.YWDID != "")
        {
            dicWheres.Add("AND JL.YWDID = {0}", req.YWDID);
        }

        ResCA<DataTable> resJL = GetYWCAQMJL(dicWheres, sOrderBy, iPage, iLimit, ref iSumCount);
        if (resJL.Code < 0)
        {
            res.Message = resJL.Message;
            return res;
        }
        
        res.Data = CryptoHelper.EncodeBase64("utf-8", JsonHelper.ToJson(resJL.Data));
        res.Code = 0;

        return res;

    }

    private ResCA<DataTable> GetYWCAQMJL(Dictionary<string, object> dicWheres, string sOrderBy, int iCurPage, int iLimit, ref int iSumCount)
    {
        ResCA<DataTable> res = new ResCA<DataTable>();
        res.Code = 0;

        string sSqlOrderBy = sOrderBy;
        if (sSqlOrderBy == null || sSqlOrderBy.Length == 0)
        {
            sSqlOrderBy = "";
        }
        else
        {
            sSqlOrderBy = string.Format(",ROW_NUMBER() OVER (ORDER BY {0}) AS _ROW ", sOrderBy);
        }

        try
        {
            using (DbSession dbSession = new DbSession(OAProviderName, OAConnString))
            {
                dbSession.ClearSql();
                dbSession.AddSql(@"
SELECT JL.JLID,JL.YWLX,
JL.YWID,JL.YWDID,JL.RQSJ,JL.RYBM,JL.STATE,JL.BZ,JL.OriginData,JL.SignedData,
JL.UseTimestamp,JL.UserType,JL.UserUid,JL.AuthorizedUserId,
JL.SealPicBase64,JL.UseQ7,JL.IncludeCertOption,JL.CertContent,
JL.ZFRYBM,JL.ZFRQSJ,JL.ZFBZ,
RY.MC AS RYMC,
ZFRY.MC AS ZFRYMC,
YWLX.MC AS YWLXMC,
CONVERT(varchar(20),JL.RQSJ,120) AS RQSJText, 
CONVERT(varchar(20),JL.ZFRQSJ,120) AS ZFRQSJText,
CASE JL.STATE WHEN 0 THEN '有效' ELSE '作废' END AS STATEText  
");
                dbSession.AddSql(sSqlOrderBy);
                dbSession.AddSql(@"  
FROM CAGL_QMJL JL
LEFT JOIN CAGL_ZD_YWLX YWLX ON JL.YWLX=YWLX.BM
LEFT JOIN ZD_RY RY ON JL.RYBM=RY.BM
LEFT JOIN ZD_RY ZFRY ON JL.ZFRYBM=ZFRY.BM
WHERE 1=1
");
                dbSession.AddWhere(dicWheres);
                string sql = dbSession.ToSqlString();
                if (iCurPage > 0 && iLimit > 0)
                {                    
                    iSumCount = dbSession.RecordCount();
                }

                LogHelper.WriteLog("获取信息:\r\n" + sql);
                res.Data = dbSession.FetchData(iCurPage, iLimit);

            }
        }
        catch (Exception e)
        {
            res.Code = -99;
            res.Message = "获取信息！" + e.Message;
        }


        return res;

    }

    private ResCA<string> CASignYWPDF(ReqCAPDFQM req)
    {
        ResCA<string> res = new ResCA<string>();
        res.Data = "";
        res.Code = -1;

        if (req.RYBM == "")
        {
            res.Message = "操作者(RYBM)为空！";
            return res;
        }

        if (req.YWID == "")
        {
            res.Message = "业务编号(YWID)为空！";
            return res;
        }

        if (req.YWLX < 0)
        {
            res.Message = "业务类型(YWLX)有误！";
            return res;
        }
        ResCA<string> resYWLX = CheckYWLX(req.YWLX);
        if (resYWLX.Code < 0)
        {
            res.Message = resYWLX.Message;
            return res;
        }

        ReqCASignPdf reqSign = new ReqCASignPdf();
        reqSign.pdfData = req.pdfData;
        reqSign.UserToken = req.UserToken;
        reqSign.UseTimestamp = req.UseTimestamp;
        reqSign.Width = req.Width;
        reqSign.Height = req.Height;
        reqSign.Page = req.Page;
        reqSign.X = req.X;
        reqSign.Y = req.Y;
        reqSign.DownLoadSealPic = false;

        ResCA<CASignPdf> resCASign = CASignPdf2(reqSign);
        if (resCASign.Code < 0)
        {
            res.Message = resCASign.Message;
            return res;
        }


        ResCA<CAPDFQMJL> resQMJL = SavePDFQMJL(req, resCASign.Data);
        if (resQMJL.Code < 0)
        {
            res.Message = resQMJL.Message;
            return res;
        }

        res.Data = CryptoHelper.EncodeBase64("utf-8", JsonHelper.ToJson(resQMJL.Data));
        res.Code = 0;

        return res;
    }

    private ResCA<CAPDFQMJL> SavePDFQMJL(ReqCAPDFQM req, CASignPdf caSign)
    {
        ResCA<CAPDFQMJL> res = new ResCA<CAPDFQMJL>();
        res.Data = new CAPDFQMJL();
        res.Code = -1;

        int iQMJL = GetQMJLID();
        if (iQMJL == 0)
        {
            res.Message = "获取签名记录ID有问题";
            return res;
        }
        res.Data.JLID = iQMJL;
        res.Data.SignedPDFBase64 = caSign.SignedPDFBase64;
        ResCA<CAQMFile> resFile = UploadPdfFile(res.Data);
        if (resFile.Code < 0)
        {
            res.Message = resFile.Message;
            return res;
        }

        string sYWSM = req.YWSM;
        sYWSM = CryptoHelper.DecodeBase64("utf-8", sYWSM);
        try
        {
            using (DbSession dbSession = new DbSession(OAProviderName, OAConnString))
            {
                dbSession.ClearSql();
                dbSession.AddSql(@"
INSERT INTO CAGL_PDFQMJL(JLID,YWID,YWDID,YWLX,RQSJ,RYBM,STATE,BZ,FilePath,SHA256,UserType,UserUid,AuthorizedUserId)
VALUES({0},{1},{2},{3},Getdate(),{4},{5},{6},{7},{8},{9},{10},{11})
",
iQMJL, req.YWID, req.YWDID, req.YWLX, req.RYBM, 0, sYWSM, resFile.Data.PATH, resFile.Data.SHA256String, 
caSign.UserType, caSign.UserUid, caSign.AuthorizedUserId
);
                LogHelper.WriteLog(dbSession.ToSqlString());
                dbSession.Execute();

                res.Data.RQSJ = GetQMJLRQSJ(iQMJL, "CAGL_PDFQMJL", "RQSJ");
                res.Code = 0;
            }
        }
        catch (Exception e)
        {
            res.Code = -99;
            res.Message = e.Message;
        }

        return res;

    }

    private ResCA<CAQMFile> UploadPdfFile(CAPDFQMJL req)
    {
        ResCA<CAQMFile> res = new ResCA<CAQMFile>();
        res.Data = new CAQMFile();
        res.Code = -1;
        string sPath = CryptoHelper.SHA256Encrypt("CAQM_"+req.JLID);
        sPath = string.Format(@"{0}/{1}/{2}.pdf", sPath.Substring(0, 1), sPath.Substring(1, 2), sPath);

        string ftpFileName = FtpRootPath + "/" + sPath;
        try
        {
            using (MemoryStream ms = new MemoryStream(Convert.FromBase64String(req.SignedPDFBase64)))
            using (FTPHelper ftp = new FTPHelper(FtpSvrHost, FtpRootPath, FtpSvrUser, FtpSvrPassword))
            {
                string[] PList = ftpFileName.Split('/');
                for (int i = 1; i < PList.Length; i++)
                {
                    string sDir = PList[i];
                    if (i != PList.Length - 1)  //目录
                    {
                        if (!ftp.IsDirectoryExist(sDir))
                        {
                            ftp.CreateDirectory(sDir);
                        }

                        ftp.GotoDirectory(sDir, false);

                    }
                    else  //文件
                    {
                        //上传前的SHA256
                        string sBStr = CryptoHelper.SHA256Encrypt(ms);
                        ms.Position = 0;  //很重要，从头上传，因为SHA256Encrypt(fs)，流的位置在末尾
                        ftp.Upload(ms, sDir);
                        using (MemoryStream ms1 = new MemoryStream())
                        {
                            ftp.Download(ms1, sDir);
                            ms1.Position = 0;
                            //上传后再下载的SHA256
                            string sEStr = CryptoHelper.SHA256Encrypt(ms1);
                            if (sBStr != sEStr)
                            {
                                res.Message = "上传后的SHA256值不一致！";
                                return res;
                            }
                            res.Data.SHA256String = sEStr;
                        }                       
                        
                    }

                }
                res.Data.PATH = ftpFileName;
                res.Code = 0;
            }

        }
        catch (Exception ex)
        {
            res.Message = ex.Message;
        }

        return res;
    }
    private ResCA<string> CASignYWPDFZF(ReqCAQMZF req)
    {
        ResCA<string> res = new ResCA<string>();
        res.Data = "";
        res.Code = -1;

        if (req.JLID == 0)
        {
            res.Message = "记录编号(JLID)为空！";
            return res;
        }

        if (req.RYBM == "")
        {
            res.Message = "操作者(RYBM)为空！";
            return res;
        }

        DataTable dtQMJL = GetQMJL("CAGL_PDFQMJL", req.JLID);
        if (dtQMJL.Rows.Count == 0)
        {
            res.Message = string.Format("没有找到编号为{0}的签名记录！", req.JLID);
            return res;
        }
        int iState = ComonHelper.ToConvert<int>(dtQMJL.Rows[0], "STATE", 0);
        int iUserType = ComonHelper.ToConvert<int>(dtQMJL.Rows[0], "UserType", 0);
        string sUserUid = ComonHelper.ToConvert<string>(dtQMJL.Rows[0], "UserUid", "");
        string sAuthorizedUserId = ComonHelper.ToConvert<string>(dtQMJL.Rows[0], "AuthorizedUserId", "");
        if (iState == 1)
        {
            res.Message = string.Format("编号为{0}的签名记录已经作废，不必再作废！", req.JLID);
            return res;
        }

        if (req.NeedCheckUserUid)
        {
            if (req.UserToken == "")
            {
                res.Message = "用户(Token)为空！";
                return res;
            }
            using (NetCAApi CaApi = new NetCAApi(NetCAUrl))
            {
                ResNetCA.OprInfoResponse resUid = CaApi.OprinfoSearch(req.UserToken);
                if (!resUid.ResponseResult.Success)
                {
                    res.Message = "CaApi.OprinfoSearch:" + resUid.ResponseResult.Message;
                    return res;
                }
                if (resUid.IsValid)
                {
                    if (iUserType == 0) //本人签名的
                    {
                        if (sUserUid != resUid.Contents.Uid && sUserUid != resUid.Contents.AuthorizedUserId)
                        {
                            res.Message = string.Format("你没有权限作废用户{0}的签名记录！", sUserUid);
                            return res;
                        }
                    }
                    else
                    {
                        if (sAuthorizedUserId != resUid.Contents.Uid && sAuthorizedUserId != resUid.Contents.AuthorizedUserId)
                        {
                            res.Message = string.Format("你没有权限作废用户{0}的签名记录！", sAuthorizedUserId);
                            return res;
                        }
                    }
                }
                else
                {
                    res.Message = string.Format("用户Token有问题！", req.UserToken);
                    return res;
                }
            }

        }

        ResCA<CAQMZFJL> resZFQMJL = CancelPDFQMJL(req);
        if (resZFQMJL.Code < 0)
        {
            res.Message = resZFQMJL.Message;
            return res;
        }

        res.Data = CryptoHelper.EncodeBase64("utf-8", JsonHelper.ToJson(resZFQMJL.Data));
        res.Code = 0;

        return res;
    }

    private ResCA<CAQMZFJL> CancelPDFQMJL(ReqCAQMZF req)
    {
        ResCA<CAQMZFJL> res = new ResCA<CAQMZFJL>();
        res.Data = new CAQMZFJL();
        res.Code = -1;


        string sZFSM = req.ZFSM;
        sZFSM = CryptoHelper.DecodeBase64("utf-8", sZFSM);
        try
        {
            using (DbSession dbSession = new DbSession(OAProviderName, OAConnString))
            {
                dbSession.ClearSql();
                dbSession.AddSql(@"
UPDATE CAGL_PDFQMJL SET STATE = 1,ZFRYBM={1},ZFBZ={2},ZFRQSJ=Getdate()
WHERE JLID={0}
",
req.JLID, req.RYBM, sZFSM
);
                LogHelper.WriteLog(dbSession.ToSqlString());
                dbSession.Execute();

                res.Data.RQSJ = GetQMJLRQSJ(req.JLID, "CAGL_PDFQMJL", "ZFRQSJ");
                res.Code = 0;
            }
        }
        catch (Exception e)
        {
            res.Code = -99;
            res.Message = e.Message;
        }

        return res;

    }

    private ResCA<string> GetYWPDFCAQMJLByJLID(ReqYWCAQMJLID req)
    {
        ResCA<string> res = new ResCA<string>();
        res.Data = "";
        res.Code = -1;
        if (req.JLID < 0)
        {
            res.Message = "记录ID(JLID)有误！";
            return res;
        }

        int iLimit = 1000;
        int iPage = 1;
        int iSumCount = 0;
        string sOrderBy = "JL.JLID";
        Dictionary<string, object> dicWheres = new Dictionary<string, object>();
        dicWheres.Add("AND JL.JLID={0} ", req.JLID);

        ResCA<DataTable> resJL = GetYWPDFCAQMJL(dicWheres, sOrderBy, iPage, iLimit, ref iSumCount);
        if (resJL.Code < 0)
        {
            res.Message = resJL.Message;
            return res;
        }

        res.Data = CryptoHelper.EncodeBase64("utf-8", JsonHelper.ToJson(resJL.Data));
        res.Code = 0;

        return res;
    }

    private ResCA<string> GetYWPDFCAQMJLByYWID(ReqYWCAQMJLYWID req)
    {
        ResCA<string> res = new ResCA<string>();
        res.Data = "";
        res.Code = -1;
        if (req.YWID == "")
        {
            res.Message = "业务编号(YWID)为空！";
            return res;
        }

        if (req.YWLX < 0)
        {
            res.Message = "业务类型(YWLX)有误！";
            return res;
        }


        int iLimit = 1000;
        int iPage = 1;
        int iSumCount = 0;
        string sOrderBy = "JL.JLID";

        Dictionary<string, object> dicWheres = new Dictionary<string, object>();
        dicWheres.Add("AND JL.YWLX = {0}", req.YWLX);
        dicWheres.Add("AND JL.YWID = {0}", req.YWID);
        if (req.YWDID != "")
        {
            dicWheres.Add("AND JL.YWDID = {0}", req.YWDID);
        }

        ResCA<DataTable> resJL = GetYWPDFCAQMJL(dicWheres, sOrderBy, iPage, iLimit, ref iSumCount);
        if (resJL.Code < 0)
        {
            res.Message = resJL.Message;
            return res;
        }

        res.Data = CryptoHelper.EncodeBase64("utf-8", JsonHelper.ToJson(resJL.Data));
        res.Code = 0;

        return res;

    }

    private ResCA<DataTable> GetYWPDFCAQMJL(Dictionary<string, object> dicWheres, string sOrderBy, int iCurPage, int iLimit, ref int iSumCount)
    {
        ResCA<DataTable> res = new ResCA<DataTable>();
        res.Code = 0;

        string sSqlOrderBy = sOrderBy;
        if (sSqlOrderBy == null || sSqlOrderBy.Length == 0)
        {
            sSqlOrderBy = "";
        }
        else
        {
            sSqlOrderBy = string.Format(",ROW_NUMBER() OVER (ORDER BY {0}) AS _ROW ", sOrderBy);
        }

        try
        {
            using (DbSession dbSession = new DbSession(OAProviderName, OAConnString))
            {
                dbSession.ClearSql();
                dbSession.AddSql(@"
SELECT JL.JLID,JL.YWLX,
JL.YWID,JL.YWDID,JL.RQSJ,JL.RYBM,JL.STATE,JL.BZ,JL.FilePath,JL.SHA256,
JL.UserType,JL.UserUid,JL.AuthorizedUserId,
JL.ZFRYBM,JL.ZFRQSJ,JL.ZFBZ,
RY.MC AS RYMC,
ZFRY.MC AS ZFRYMC,
YWLX.MC AS YWLXMC,
CONVERT(varchar(20),JL.RQSJ,120) AS RQSJText, 
CONVERT(varchar(20),JL.ZFRQSJ,120) AS ZFRQSJText,
CASE JL.STATE WHEN 0 THEN '有效' ELSE '作废' END AS STATEText  
");
                dbSession.AddSql(sSqlOrderBy);
                dbSession.AddSql(@"  
FROM CAGL_PDFQMJL JL
LEFT JOIN CAGL_ZD_YWLX YWLX ON JL.YWLX=YWLX.BM
LEFT JOIN ZD_RY RY ON JL.RYBM=RY.BM
LEFT JOIN ZD_RY ZFRY ON JL.ZFRYBM=ZFRY.BM
WHERE 1=1
");
                dbSession.AddWhere(dicWheres);
                string sql = dbSession.ToSqlString();
                if (iCurPage > 0 && iLimit > 0)
                {
                    iSumCount = dbSession.RecordCount();
                }

                LogHelper.WriteLog("获取信息:\r\n" + sql);
                res.Data = dbSession.FetchData(iCurPage, iLimit);

            }
        }
        catch (Exception e)
        {
            res.Code = -99;
            res.Message = "获取信息！" + e.Message;
        }


        return res;

    }


  }

  public class ReqApiCA
  {
    /// <summary>
    /// 功能号 String 是。
    /// </summary>
    public string func { get; set; }

    /// <summary>
    /// 请求业务参数 data String 是
    /// 各接口请求业务参数的内容不同，实际内容以各接口接口为准；
    /// 接口请求业务参数值，并且做 base64 编码,编码字符集 UTF-8
    /// </summary>
    public string data { get; set; }

  }

  public class ReqUserRegister
  {
    public ReqNetCA.User User { get; set; }

    public string AuthId { get; set; }
    public int UserType { get; set; }
    
  }

  public class ReqUserUnLock
  {
    public string UserUid { get; set; }

    public string AuthId { get; set; }

    public string Name { get; set; }

  }

  public class ReqUserCertContent
  {
    public string UserUid { get; set; }

    public string AuthId { get; set; }
    
  }

  public class ReqUserInfo
  {
    public string UserUid { get; set; }


  }

  public class ReqUserCert
  {
      public string CertContent { get; set; }
  }

  public class ReqCAQM : ReqCASign
  {
      public string YWID { get; set; }

      public string YWDID { get; set; }

      public int YWLX { get; set; }

      public string YWSM { get; set; }

      public string RYBM { get; set; }
  }

  public class CAQMJL
  {
      public int JLID { get; set; }

      public string RQSJ { get; set; }

      public string SealPicBase64 { get; set; }
  }

  public class ReqCAQMZF
  {
      public int JLID { get; set; }

      public string RYBM { get; set; }

      public string ZFSM { get; set; }

      public bool NeedCheckUserUid { get; set; }

      public string UserToken { get; set; }
  }

  public class CAQMZFJL
  {
      public string RQSJ { get; set; }

  }


  public class ReqYWCAQMJLID
  {
      public int JLID { get; set; }
  }

  public class ReqYWCAQMJLYWID
  {
      public string YWID { get; set; }

      public string YWDID { get; set; }

      public int YWLX { get; set; }
  }

  public class YWCAQMJL
  {
      public int JLID { get; set; }

      public string YWID { get; set; }

      public int YWLX { get; set; }

      public string YWSM { get; set; }

      public string RYBM { get; set; }

      public string RQSJ { get; set; }

      public string ZFRYBM { get; set; }

      public string ZFRQSJ { get; set; }

      public string ZFSM { get; set; }

      public int STATE { get; set; }

      public string OriginData { get; set; }

      /// <summary>
      /// 是否携带签名时间戳，默认 false，不携带时间戳
      /// </summary>
      public bool UseTimestamp { get; set; }

      /// <summary>
      /// 是否使用国密signedData, false表示不使用。
      /// </summary>
      public bool UseQ7 { get; set; }

      /// <summary>
      /// 包含证书的标识，目前仅能包含自身签名证书，1	不包含签名证书 2	包含签名证书
      /// </summary>
      public int IncludeCertOption { get; set; }

      /// <summary>
      /// userType	Int	0表示证书用户 1表示被授权用户
      /// </summary>
      public int UserType { get; set; }

      /// <summary>
      /// authorizedUserId	Int	被授权用户id，userType为0时该值为空
      /// </summary>
      public string AuthorizedUserId { get; set; }

      public string UserUid { get; set; }

      public string SealPicBase64 { get; set; }


  }

  public class ReqCAPDFQM : ReqCASignPdf
  {
      public string YWID { get; set; }

      public string YWDID { get; set; }

      public int YWLX { get; set; }

      public string YWSM { get; set; }

      public string RYBM { get; set; }
  }

  public class CAPDFQMJL
  {
      public int JLID { get; set; }

      public string RQSJ { get; set; }

      public string SignedPDFBase64 { get; set; }

  }

  public class CAQMFile
  {
      public string PATH { get; set; }

      public string SHA256String { get; set; }
  }

}